import { DrawArea, Target2D } from "../functions/image/image.js";
import * as DOM from "../functions/dom/domtool.js";
import { Editor } from "./pixeleditor.js";
import { DrawTool, DrawToolCenter } from "./drawtool.js";
import { Color32 } from "../functions/image/color.js";
import { DrawLayer } from "./drawlayer.js"
//切分画板相应功能
export class PixelEdit_DrawCanvas {

    constructor() {
        this._layers.push(new DrawLayer());
        this.op_backlayer = new DrawLayer();
        this.op_backlayer.updateBitmap();
        
        this._finalbitmap = new DrawArea(32, 32);

        this._finalbitmap.updateBitmap();
    }
    IsSelect(): boolean {
        return this.getCurrentLayer().getSelect() != null;
    }

    drawColor: Color32 = new Color32(0, 0, 0, 255);
    setDrawColor(color: Color32): void {
        this.drawColor = color.Clone();
    }
    getDrawColor(): Color32 {
        return this.drawColor.Clone();
    }
    setBackColor(color: Color32): void {
        this.canvas.setBackColor(color);
    }
    editor: Editor;

    //图层相关
    private _layers: DrawLayer[] = []
    getCurrentLayer(): DrawLayer {
        return this._layers[0];
    }
    private _finalbitmap: DrawArea;//还是用这个省心
    GetFinalBitmap(): Target2D {
        return this._finalbitmap;
    }

    SetSize(width: number, height: number) {
        this._finalbitmap.setWidth(width);
        this._finalbitmap.setHeight(height);
        for (var i = 0; i < this._layers.length; i++) {
            this._layers[i].setWidth(width);
            this._layers[i].setHeight(width);
        }
        this.op_backlayer.setWidth(width);
        this.op_backlayer.setHeight(height);
    }
    getWidth(): number {
        return this._finalbitmap.getWidth();
    }
    getHeight(): number {
        return this._finalbitmap.getHeight();
    }
    Resize_Scale(neww: number, newh: number, linear: boolean): void {
        this._finalbitmap.setWidth(neww);
        this._finalbitmap.setHeight(newh);
        for (var i = 0; i < this._layers.length; i++) {
            this._layers[i].Resize_Scale(neww, newh, linear);
        }
        this.op_backlayer.Resize_Scale(neww, newh, linear);

    }
    Resize_Cut(neww: number, newh: number, dirx: number, diry: number): void {
        this._finalbitmap.setWidth(neww);
        this._finalbitmap.setHeight(newh);
        for (var i = 0; i < this._layers.length; i++) {
            this._layers[i].Resize_Cut(neww, newh, dirx, diry);
        }
        this.op_backlayer.Resize_Cut(neww, newh, dirx, diry);
    }
    private _scale: number = 1.0;
    canvas: DOM.Canvas; //主画板控件
    op_grid: boolean = true;
    op_backpicshow: boolean = true;
    op_backlayer: DrawLayer;
    Init(editor: Editor) {
        this.editor = editor;

        let canvas = this.canvas
        let priview = editor.priview

        canvas.RePaint = this.RePaint.bind(this);

        let press = false;
        let ctrlmode = false
        canvas._root.onmousedown = (e) => {
            //canvas仅限左键操作
            if (e.button != 0)
                return;
            let x = e.offsetX / this._scale + editor.priview.rectX;
            let y = e.offsetY / this._scale + editor.priview.rectY;
            if (!e.ctrlKey) {
                ctrlmode = false;
                this.OnToolMouseLeftDown(x | 0, y | 0);
            }
            else {
                ctrlmode = true;
            }
            press = true;

        };
        canvas._root.onmousemove = (e) => {
            let x = this._LastDrawX = e.offsetX / this._scale + editor.priview.rectX;
            let y = this._LastDrawY = e.offsetY / this._scale + editor.priview.rectY;

            //console.log(e.button);
            let _elayer = canvas._root;
            if (ctrlmode && press) {
                //ctrl 用来移动画布
                //处理点在红框之外
                let fh = _elayer.clientHeight;
                let scale = fh / editor.priview.imgheight;


                //移动红框
                editor.priview.rectX -= e.movementX / scale;
                editor.priview.rectY -= e.movementY / scale;

                //不让红框离开canvas
                editor.priview.Refresh();
            }
            else if (press) {
                //let idata = new ImageData(21, 21);

                this.OnToolMouseLeftMove(x | 0, y | 0);


            }
            editor.priview.Refresh();
        }
        window.addEventListener("mouseup", (e) => {
            if (press) {
                press = false;

                let x = e.offsetX / this._scale + editor.priview.rectX;
                let y = e.offsetY / this._scale + editor.priview.rectY;
                if (!ctrlmode) {
                    this.OnToolMouseLeftUp(x | 0, y | 0);
                }

            }
        });
        //先刷一次
        canvas.Refresh();
        //canvas.getC2D().drawImage(img, 0, 0, img.width * 4, img.height * 4);
        priview.onChange = () => {
            canvas.Refresh();
        }
        priview.onChangeScale = (v) => {
            this._scale = v;
            this.RePaint();
        }
        canvas._root.addEventListener('mousewheel', (e) => {

            if ((e as any).wheelDelta) {
                let delta = (e as any).wheelDelta as number;
                if ((event as any).ctrlKey) {
                    if (delta > 0)
                        editor.priview._range.valueAdd();
                    else if (delta < 0)
                        editor.priview._range.valueDec();


                }
                else {
                    this.OnToolMouseWheel(delta);
                }
            }

        });

    }

    RePaint(): void {

        if (this.editor == null || this.editor.priview == null)
            return;
        let _c2d = this.canvas.getC2D();

        let radio = _c2d.canvas.width / _c2d.canvas.height;

        this.editor.priview.rectHeight = _c2d.canvas.height / this._scale;

        this.editor.priview.rectWidth = this.editor.priview.rectHeight * radio;

        _c2d.imageSmoothingEnabled = false;

        let x = this.editor.priview.rectX | 0;
        let y = this.editor.priview.rectY | 0;
        let w = this.editor.priview.rectWidth | 0;
        let h = this.editor.priview.rectHeight | 0;

        //绘制图层
        this._finalbitmap.getContext().clearRect(0, 0, this._finalbitmap.getWidth(), this._finalbitmap.getHeight());
        for (var i = 0; i < this._layers.length; i++) {
            let img = this._layers[i].getBitmap();

            this._finalbitmap.getContext().drawImage(img, 0, 0);

            let imgselect = this._layers[i].getBitmapSelect();
            if (imgselect != null)
                this._finalbitmap.getContext().drawImage(imgselect, 0, 0);
        }
        this._finalbitmap.updateBitmap();





        let fimg = this._finalbitmap.getBitmap();

        //绘制参考层
        if (this.op_backpicshow) {
            let img = this.op_backlayer.getBitmap();
            if (img != null)
                _c2d.drawImage(img, x, y, w, h, 0, 0, _c2d.canvas.width | 0, _c2d.canvas.height | 0);

            let imgselect = this.op_backlayer.getBitmapSelect();
            if (imgselect != null)
                _c2d.drawImage(imgselect, x, y, w, h, 0, 0, _c2d.canvas.width | 0, _c2d.canvas.height | 0);
        }
        _c2d.drawImage(this._finalbitmap.getBitmap(), x, y, w, h, 0, 0, _c2d.canvas.width | 0, _c2d.canvas.height | 0);


        this.editor.priview.Refresh();


        let pixelw = _c2d.canvas.width / w;
        let pixelh = _c2d.canvas.height / h;

        if (this.op_grid) {
            this.paint_Grid(pixelw, pixelh);
        }

        //预览图标
        this.OnToolPreview_InCanvas(this._LastDrawX, this._LastDrawY, pixelw, pixelh);

        //遮蔽超出区域
        if (x + w > fimg.width) {
            let w2 = fimg.width - x;
            _c2d.fillStyle = "#777";
            _c2d.fillRect(pixelw * w2, 0, _c2d.canvas.width - pixelw * w2, _c2d.canvas.height);
        }
        if (y + h > fimg.height) {
            let h2 = fimg.height - y
            _c2d.fillStyle = "#777";
            _c2d.fillRect(0, pixelh * h2, _c2d.canvas.width, _c2d.canvas.height - pixelh * h2);
        }


    }
    paint_Grid(pixelw: number, pixelh: number) {
        let _c2d = this.canvas.getC2D();
        let x = this.editor.priview.rectX | 0;
        let y = this.editor.priview.rectY | 0;
        let w = this.editor.priview.rectWidth | 0;
        let h = this.editor.priview.rectHeight | 0;
        //不可避免的会出现一点偏差，重新算一个像素的宽度


        {
            let gridscale = 16;
            {//画浅格
                _c2d.strokeStyle = "#333";
                _c2d.beginPath();
                //不可避免的会出现一点偏差，重新算一个像素的宽度


                //显示几个像素为一格

                if (this._scale >= 16) {
                    gridscale = 1.0
                }
                else if (this._scale >= 8.0) {
                    gridscale = 2.0;

                }
                else if (this._scale >= 4.0) {
                    gridscale = 4.0;

                }
                else if (this._scale >= 2.0) {
                    gridscale = 8.0;

                }
                else {
                    gridscale = 16.0;

                }

                //画横线
                for (var i = 0; i < _c2d.canvas.height; i += pixelh * gridscale) {

                    _c2d.moveTo(0, i);
                    _c2d.lineTo(_c2d.canvas.width, i);

                }
                //画竖线
                for (var i = 0; i < _c2d.canvas.width; i += pixelw * gridscale) {

                    _c2d.moveTo(i, 0);
                    _c2d.lineTo(i, _c2d.canvas.height);

                }
                _c2d.closePath();
                _c2d.stroke();
            }
            if (this._scale > 1.0) {//画深格
                _c2d.strokeStyle = "#888";
                _c2d.beginPath();



                //显示几个像素为一格

                let deepw = (y % 16);

                //画横线
                for (var i = 0; i < _c2d.canvas.height; i += pixelh * gridscale) {

                    if (deepw >= 16) {
                        _c2d.moveTo(0, i);
                        _c2d.lineTo(_c2d.canvas.width, i);
                        deepw = 0;
                    }
                    deepw += gridscale;
                }


                deepw = (x % 16);
                //画竖线
                for (var i = 0; i < _c2d.canvas.width; i += pixelw * gridscale) {

                    if (deepw >= 16) {
                        _c2d.moveTo(i, 0);
                        _c2d.lineTo(i, _c2d.canvas.height);
                        deepw = 0;
                    }
                    deepw += gridscale;
                }
                _c2d.closePath();
                _c2d.stroke();
            }
        }
    }

    private OnToolMouseLeftDown(x: number, y: number): void {
        let tag = this.editor.toolbar.getPickTag();
        let dot = parseInt(this.editor.toolbarsize.getPickTag());
        let color = this.getDrawColor();
        let tool = DrawToolCenter.GetDrawTool(tag);
        if (tool != undefined) {
            tool.SetLineWidth(dot);
            tool.OnLeftDown(this.getCurrentLayer(), x, y, color);
            this.RePaint();
        }
    }
    private OnToolMouseLeftMove(x: number, y: number): void {
        let tag = this.editor.toolbar.getPickTag();
        let dot = parseInt(this.editor.toolbarsize.getPickTag());
        let color = this.getDrawColor();
        let tool = DrawToolCenter.GetDrawTool(tag);
        if (tool != undefined) {
            tool.SetLineWidth(dot);
            tool.OnLeftMove(this.getCurrentLayer(), x, y, color);
            this.RePaint();
        }

    }
    private OnToolMouseLeftUp(x: number, y: number): void {
        let tag = this.editor.toolbar.getPickTag();
        let color = this.getDrawColor();
        let tool = DrawToolCenter.GetDrawTool(tag);
        if (tool != undefined) {
            tool.OnLeftUp(this.getCurrentLayer(), x, y, color);
            this.RePaint();
        }
    }
    private OnToolMouseWheel(delta: number): void {
        let tag = this.editor.toolbar.getPickTag();

        let tool = DrawToolCenter.GetDrawTool(tag);
        if (tool != undefined) {
            tool.OnToolMouseWheel(this.getCurrentLayer(), delta);
            this.RePaint();
        }
    }
    private OnToolPreview_InCanvas(x: number, y: number, pixelw: number, pixelh: number): void {
        let tag = this.editor.toolbar.getPickTag();
        let color = this.getDrawColor();

        let tool = DrawToolCenter.GetDrawTool(tag);
        if (tool != undefined) {
            tool.OnPreview_InCanvas(this.canvas._c2d, x, y, this.editor.priview.rectX | 0, this.editor.priview.rectY | 0, pixelw, pixelh, color);
        }
        let offx = this.editor.priview.rectX;
        let offy = this.editor.priview.rectY;


        //绘制选区
        if (this.editor.drawCanvas.getCurrentLayer().getSelect() != null) {
            let timer = this.editor.timer * 2;
            if (timer > 1) timer = 2 - timer;

            let s = this.editor.drawCanvas.getCurrentLayer().getSelect();
            let c = new Color32(255 * timer, 58, 255 * (1 - timer), 200);
            this.canvas._c2d.globalAlpha = 0.5;
            DrawTool.DrawRect(this.canvas._c2d, s.x1 - offx, s.y1 - offy, s.x2 - offx, s.y2 - offy, c, 1, pixelw, pixelh);
            this.canvas._c2d.globalAlpha = 1.0;
        }

    }
    private _LastDrawX: number;
    private _LastDrawY: number;

}